/*************************************************
 * HISTORY:                                      *
 *	06/22/2020 pyx : Created.                    *
 *	06/01/2022 pyx : Edited.                     *
=================================================*/

#ifndef DADUMPER_CONNECTOR_H
#define DADUMPER_CONNECTOR_H

#define MAX_BATCH_SIZE 10240
#define SYMBOL_VECTOR_DIM 300


#include <iostream>
#include <sstream>
#include <memory>
#include <string>
#include <stdexcept>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <fstream>
#include <cassert>

#include "DAType.h"

#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/metadata.h>
#include <cppconn/exception.h>

#define DBHOST "tcp://127.0.0.1:3306"
#define USER "root"
#define PASSWORD "123456"

#define USE_DEF_AND_DEC_TO_MAP 1

class Connector
{

public:
    Connector(std::string directory);
    Connector(std::string directory, std::string vectorsfile);
    ~Connector();

    struct Symbol
    {
        unsigned sid;
        std::string signature;
        unsigned st;
        std::string name;
    };

    struct Ref
    {
        unsigned sid;
        unsigned rt;
        unsigned fid;
        std::string loc;
    };

    void findFileDep();

    void dumpSymbolNode();
    void dumpSymbolDep();
    void dumpFileDefSymMap();
    void dumpNewVectors();
    void dumpOnehotVectors();

    void dumpRefNode(std::string tablename);

    void searchDec(unsigned sid, unsigned notfid, SymbolType st);
    void searchDef(unsigned sid, unsigned notfid, SymbolType st);

    void dumpDepFileList();
    void dumpDepFileList_funct();
    void dumpDepFileList_gv();
    void dumpDepFileList_macro();
    void dumpDepFileList_type();
    void dumpDepFileList_enum();
    void dumpDepFileList_struct();
    void dumpDepFileList_union();
    void dumpDepFileList_typedef();
    void dumpDepFileList_field();
    void dumpDepFileList_functgv();
    
    void dumpFileSymbol(unsigned fid,bool symmdgprint);

    void commit();

private:
    void startDump();

    sql::Driver *driver;
    sql::Connection *con;
    sql::Statement *stmt;

    std::string directory;
    std::string vectorsfile;

    std::string currfilepath;//don't change after init!
    unsigned currfid;

    bool connbegin = true;
    bool includebegin = true;
    bool includetsebegin = true;
    bool symboltsebegin = true;
    bool fgvtsebegin = true;
    bool funtsebegin = true;

    //std::vector<unsigned> sidlist;

    unsigned getfid(std::string filepath);
    std::string getfilepath(unsigned fid);

    //Symbol *getSymbol(unsigned sid);
    SymbolType getSymbolType(unsigned sid);
    std::string getSymbolName(unsigned sid);
    std::string getSymbolQN(unsigned sid);
    //bool isInternalSymbol(unsigned sid);
    std::unordered_set<std::string> getSymbolDefFilepath(unsigned sid);
    std::unordered_set<std::string> getSymbolDefAndDecFilepath(unsigned sid);


    std::string getRelativeFilePath(std::string filepath);

    std::unordered_set<unsigned> depfilelist;//currfid dep fid (defuse dep)
    std::unordered_set<unsigned> depfilelist_funct;//3
    std::unordered_set<unsigned> depfilelist_gv;//4
    std::unordered_set<unsigned> depfilelist_macro;//6
    std::unordered_set<unsigned> depfilelist_type;//0 10 11 12
    std::unordered_set<unsigned> depfilelist_enum;//0
    std::unordered_set<unsigned> depfilelist_struct;//10
    std::unordered_set<unsigned> depfilelist_union;//12
    std::unordered_set<unsigned> depfilelist_typedef;//11
    std::unordered_set<unsigned> depfilelist_field;//1 2


    std::unordered_set<unsigned> depsidlist;//symbol is has symbol dep

    //std::unordered_map<unsigned, unsigned> filerefcounter;//file reffed times by currfile

    std::unordered_map<unsigned, std::unordered_set<unsigned>> filesymbolmap;//symbol reffed by currfile located in fid

    std::unordered_map<unsigned, std::unordered_set<std::string>> filedefsymbolmap;//fid->sid(dec&def)
};

#endif //DADUMPER_CONNECTOR_H
